package com.yanqu.road.server.manager.union.unionrank;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.servercenter.ServerGroup;
import com.yanqu.road.entity.union.cross.CrossUnionInfo;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.pb.union.UnionProto;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.union.CrossUnionMgr;
import com.yanqu.road.server.manager.union.activitygroup.UnionActivityGroupLockMgr;
import com.yanqu.road.server.manger.CrossUnionServerGroupMgr;
import com.yanqu.road.server.manger.ServerGroupMgr;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 管理商会排行消息缓存
 */
public class CrossUnionRankMsgCacheMgr extends TempCrossMgr {
    //缓存商会分组活动,活动内所有商会的排行的缓存,当前总赚速排行 key=activityId,活动过期移出内存
    private static Map<Integer, CrossUnionRankCache> unionActivityGroupRankCacheMap = new ConcurrentHashMap<>();
    //跨服商会分组榜单缓存,当前总赚速排行
    private static Map<Integer, CrossUnionRankCache> unionGroupRankCacheMap = new ConcurrentHashMap<>();
    //郊区榜单分组缓存,当前总赚速排行
    private static Map<Integer, CrossUnionRankCache> unionCrossRankCacheMap = new ConcurrentHashMap<>();

    /**
     * 获取商会分组活动的排行,type为1,取活动内所有商会的排行才用这个接口
     *
     * @param activityId
     * @return
     */
    public static RankProto.UnionRankListMsg getUnionActivityRankMsgByActivityId(int activityId) {
        ActivityInfo activityInfo = UnionActivityGroupLockMgr.getActivityInfoMap().get(activityId);
        if (activityInfo == null) {
            return RankProto.UnionRankListMsg.newBuilder().build();
        }

        CrossUnionRankCache cache = unionActivityGroupRankCacheMap.get(activityId);
        if (cache == null) {
            synchronized (unionActivityGroupRankCacheMap) {
                cache = unionActivityGroupRankCacheMap.get(activityId);
                if (cache == null) {
                    int groupUnionNum = Integer.valueOf(activityInfo.getUnionGroup().split("\\|")[1]);
                    int groupNum = UnionActivityGroupHelper.getGroupNum(activityInfo);
                    int rankNum = groupNum * groupUnionNum + 50;
                    cache = new CrossUnionRankCache(activityId, rankNum);
                    unionActivityGroupRankCacheMap.put(activityId, cache);
                }
            }
        }

        long rankRefreshSecond = 40; //40秒更新一次

        if (cache.isNeedUpdateRank(rankRefreshSecond)) {
            synchronized (cache) {
                if (cache.isNeedUpdateRank(rankRefreshSecond)) {
                    List<CrossUnionInfo> infoList = CrossUnionMgr.getUnionListByServerList(activityInfo.getServerIdList());
                    // v6.9 隋唐改为赚钱
                    if (activityInfo.getType() == eActivityType.SuiTang.getValue()
                            || activityInfo.getType() == eActivityType.ChuHanZB.getValue()
                            || activityInfo.getType() == eActivityType.FiveHero.getValue()) {
                        infoList.sort(Comparator.comparing(CrossUnionInfo::getTotalMaxAbility).reversed());
                    } else {
                        infoList.sort(Comparator.comparing(CrossUnionInfo::getTotalEarnSpeed).reversed());
                    }


                    RankProto.UnionRankListMsg.Builder saveRankBuilder = RankProto.UnionRankListMsg.newBuilder();
                    for (int i = 0; i < infoList.size() && i < cache.getRankNum(); i++) {
                        CrossUnionInfo unionInfo = infoList.get(i);
                        RankProto.UnionRankTempMsg.Builder builder = RankProto.UnionRankTempMsg.newBuilder();
                        builder.setUnionUid(unionInfo.getUnionUid());
                        builder.setUnionBaseData(UnionBasePb.parseUnionBaseTempMsg(CrossUnionMgr.parseUnionBaseInfo(unionInfo)));
                        // v6.9 隋唐改为赚钱
                        if (activityInfo.getType() == eActivityType.SuiTang.getValue()
                                || activityInfo.getType() == eActivityType.ChuHanZB.getValue()
                                || activityInfo.getType() == eActivityType.FiveHero.getValue()) {
                            builder.setValue(unionInfo.getTotalMaxAbility().toString());
                        } else {
                            builder.setValue(unionInfo.getTotalEarnSpeed().toString());
                        }

                        saveRankBuilder.addRankList(builder);
                    }
                    cache.setRankMsg(saveRankBuilder.build());
                }
            }
        }

        return cache.getRankMsg();
    }

    /**
     * 郊区榜单商会分组的商会榜单
     */
    public static RankProto.UnionRankListMsg getServerUnionGroupRankMsg(long serverId) {
        int groupId = CrossUnionServerGroupMgr.getGroupIdByServerId(serverId);
        Set<Long> serverIdSet = CrossUnionServerGroupMgr.getGroupServer(groupId);

        CrossUnionRankCache cache = unionGroupRankCacheMap.get(groupId);
        if (cache == null) {
            synchronized (unionGroupRankCacheMap) {
                cache = unionGroupRankCacheMap.get(groupId);
                if (cache == null) {
                    cache = new CrossUnionRankCache(groupId, 500);
                    unionGroupRankCacheMap.put(groupId, cache);
                }
            }
        }

        long rankRefreshSecond = 10; //10秒更新一次

        if (cache.isNeedUpdateRank(rankRefreshSecond)) {
            synchronized (cache) {
                if (cache.isNeedUpdateRank(rankRefreshSecond)) {
                    List<CrossUnionInfo> infoList = CrossUnionMgr.getUnionListByServerList(serverIdSet);

                    infoList.sort(Comparator.comparing(CrossUnionInfo::getTotalEarnSpeed).reversed());

                    RankProto.UnionRankListMsg.Builder saveRankBuilder = RankProto.UnionRankListMsg.newBuilder();
                    for (int i = 0; i < infoList.size(); i++) {
                        CrossUnionInfo unionInfo = infoList.get(i);
                        RankProto.UnionRankTempMsg.Builder builder = RankProto.UnionRankTempMsg.newBuilder();
                        builder.setUnionUid(unionInfo.getUnionUid());
                        builder.setUnionBaseData(UnionBasePb.parseUnionBaseTempMsg(CrossUnionMgr.parseUnionBaseInfo(unionInfo)));
                        builder.setValue(unionInfo.getTotalEarnSpeed().toString());
                        builder.addAllRankGrade(CrossUnionMgr.getMemberRankGradeMsg(unionInfo));
                        for (Map.Entry<Integer, Integer> gradeEntry : unionInfo.getGradeAmountMap().entrySet()) {
                            builder.addOriginalGradeAmount(UnionProto.UnionRankGradeJoinLimitTemp.newBuilder().setGradeId(gradeEntry.getKey()).setNum(gradeEntry.getValue()));
                        }
                        saveRankBuilder.addRankList(builder);
                    }
                    cache.setRankNum(infoList.size());
                    cache.setRankMsg(saveRankBuilder.build());
                }
            }
        }

        return cache.getRankMsg();
    }

    /**
     * 郊区榜单分组的商会榜单
     * @param serverId
     * @return
     */
    public static RankProto.UnionRankListMsg getUnionCrossRankMsg(long serverId) {
        int groupId = ServerGroupMgr.getGroupIdByServerId(serverId);
        return getUnionCrossRankMsgByGroupId(groupId);
    }

    public static RankProto.UnionRankListMsg getUnionCrossRankMsgByGroupId(int groupId) {
        ServerGroup serverGroupByServerId = ServerGroupMgr.getServerGroup(groupId);
        if (serverGroupByServerId == null) {
            return null;
        }

        CrossUnionRankCache cache = unionCrossRankCacheMap.get(groupId);
        if (cache == null) {
            synchronized (unionCrossRankCacheMap) {
                cache = unionCrossRankCacheMap.get(groupId);
                if (cache == null) {
                    cache = new CrossUnionRankCache(groupId, GameConfig.RANK_DEFAULT_MAX_COUNT);
                    unionCrossRankCacheMap.put(groupId, cache);
                }
            }
        }

        long rankRefreshSecond = 5; //10秒更新一次

        if (cache.isNeedUpdateRank(rankRefreshSecond)) {
            synchronized (cache) {
                if (cache.isNeedUpdateRank(rankRefreshSecond)) {
                    List<CrossUnionInfo> infoList = CrossUnionMgr.getUnionListByServerList(serverGroupByServerId.getServerList());

                    infoList.sort(Comparator.comparing(CrossUnionInfo::getTotalEarnSpeed).reversed());

                    RankProto.UnionRankListMsg.Builder saveRankBuilder = RankProto.UnionRankListMsg.newBuilder();
                    for (int i = 0; i < infoList.size() && i < cache.getRankNum(); i++) {
                        CrossUnionInfo unionInfo = infoList.get(i);
                        RankProto.UnionRankTempMsg.Builder builder = RankProto.UnionRankTempMsg.newBuilder();
                        builder.setUnionUid(unionInfo.getUnionUid());
                        builder.setUnionBaseData(UnionBasePb.parseUnionBaseTempMsg(CrossUnionMgr.parseUnionBaseInfo(unionInfo)));
                        builder.setValue(unionInfo.getTotalEarnSpeed().toString());
                        saveRankBuilder.addRankList(builder);
                    }
                    cache.setRankMsg(saveRankBuilder.build());
                }
            }
        }

        return cache.getRankMsg();
    }


    @Override
    public boolean removeExpireData() throws Exception {
        List<Integer> needRemoveIdList = new ArrayList<>();
        for (CrossUnionRankCache rankCache : unionActivityGroupRankCacheMap.values()) {
            int activityId = rankCache.getKeyId();
            ActivityInfo activityInfo = UnionActivityGroupLockMgr.getActivityInfoMap().get(activityId);
            if (activityInfo == null || !ActivityMgr.activityInShowTime(activityInfo)) {
                needRemoveIdList.add(activityId);
            }
        }

        for (Integer activityId : needRemoveIdList) {
            unionActivityGroupRankCacheMap.remove(activityId);
        }

        return true;
    }

    @Override
    public boolean init() throws Exception {
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }
}
